package com.leyou.gateway.filters;

import com.leyou.common.auth.entity.UserInfo;
import com.leyou.common.auth.utils.JwtUtils;
import com.leyou.common.utils.CookieUtils;
import com.leyou.gateway.config.FilterProperties;
import com.leyou.gateway.config.JwtProperties;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

//网关要校验用户是否，登录，如果没有登录，从网关拒绝请求
@Component
@Slf4j
@EnableConfigurationProperties(FilterProperties.class)
public class UserTokenFilter extends ZuulFilter {

    @Autowired
    private JwtProperties props;

    @Autowired
    private FilterProperties filterProperties;

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return FilterConstants.SERVLET_DETECTION_FILTER_ORDER - 1;
    }

    //返回true表示过滤器生效，返回false 表示过滤器无效
    @Override
    public boolean shouldFilter() {
        RequestContext currentContext = RequestContext.getCurrentContext();

        //获取请求对象
        HttpServletRequest request = currentContext.getRequest();

        //实际请求的资源信息
        String requestURI = request.getRequestURI();

        //allowPath每一个要放行的路径
        for (String allowPath : filterProperties.getAllowPaths()) {
            //如果请求路径以放行路径开始，则直接放行
            if (requestURI.startsWith(allowPath)){
                return false;
            }
        }


        return true;
    }

    /**
     * 过滤器中，放行，不用做任何通知，拦截，需要声明，拦截就是不响应
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        RequestContext currentContext = RequestContext.getCurrentContext();

        //获取请求对象
        HttpServletRequest request = currentContext.getRequest();

        //获取请求的资源地址
        String requestURI = request.getRequestURI();

        try {
            //获取token
            String token = CookieUtils.getCookieValue(request, props.getUser().getCookieName());

            //解析token
            JwtUtils.getInfoFromToken(token,props.getPublicKey(), UserInfo.class);

            log.info("【网关】对用户的登录状态验证通过，请求目标路径为:{}",requestURI);
        } catch (Exception e) {
            log.error("【网关】对用户的登录状态验证失败，请求目标路径为:{}",requestURI);
            currentContext.setSendZuulResponse(false);//设置响应为false，不响应
            currentContext.setResponseStatusCode(401); //未授权（没有登录）
        }

        return null;
    }
}
